#ifndef LIB_PLUGIN_H_INCLUDED
#define LIB_PLUGIN_H_INCLUDED

#include "../../Base/lib/lib.queue.h"
#include "../../Base/lib/lib.hashtable.h"
#include "../../Base/lib/lib.dlt.h"
#include "../../Base/lib/lib.log.h"

#include <time.h>

#ifdef __cplusplus
extern "C"
{
#endif

/**<
UTC_now$plugin_name1:lastrun:exit_code$plugin_name2:lastrun:exit_code...... \0

11(for_time_t) +Numer_of_plugins*(1+MAX_LENGTH_OF_PLUGIN_NAME+1+11(for_last_run)+4(for_exit_code))   +1(for\0)
*/

#define SHM_MEM_SIZE_BASE_PER_PLUGIN 1+MAX_LENGTH_OF_PLUGIN_NAME+1+11+4


/*
#define RUN_ONCE                    0
#define RUN_INDEPENDENT_DAEMON      1
#define RUN_EVERY_CYCLE             2
*/

    typedef struct pluginItem {
    	/**<  the plugin function handle */
        void *handler;

        /**< If the plugin is required, run failure of the plugin will result in daemon failue
        immediately. */
        short isRequired;

        char pluginName[MAX_LENGTH_OF_PLUGIN_NAME];

/*      0 run once
        1 run as a independent daemon
        2 run every xx second

        unsigned short runType;

        *< 0 means run once. greater than 0 means the real runFrequncy
        unsigned int runFrequncy;

*/

        /**< Hashkey for finding the plugin in the buket */
        char *hkey;

        /**< The initial value is 0 */
        time_t lastRun;

    } pluginItem;

    /*******************************************************************
    *            Functions that a plugin needs to implement            *
    *                                                                  *
    *******************************************************************/

    BOOL getPluginRequire();

/*    int getPluginRunType();*/

/*    unsigned int getPluginRunFrequncy();*/


    /*! This function is used to check whether the configuration is corropted.
        This function will be triggered if the getPluginRequire return
        2)BOOL preRunPlugin(int type);
        Optional
    */
/*    BOOL preRunPlugin();*/


    /*! @fn
            reportStatus
        @description
            This function is to report status of the run_as_indenpendent_daemon plugin after default initialization is done.
        @require
            Required if the plugin runs as a indenpendent_daemon.
    */
/*    BOOL reportPluginStatus(void *pipe);*/


    /*! @fn
            execPlugin();
        @require
            Please notice that you have to maintain the plugin running mechanism.
            E.g.
            If your plugin restricts that only one instance can be running at the same time.
            And the plugin will run every 5 mins.
            Then you have to find a way to control it. The main daemon will schedule it every
            5 mins. It will be triggered anyway.
    */
    BOOL execPlugin();

    /*! @fn
            pluginExit
        @require
            Optional
            Required if the plugin is running as a independent daemon.
    */
    BOOL exitPlugin();

    /*******************************************************************
    *            END (Functions that a plugin needs to implement)      *
    *******************************************************************/


    dLinkList* initPlugins(hTab *hcf);

    /*! @fn CheckPluginConf
        @author Guannan
            Required
        @return
            1 means not corrupted. 0 means corrupted.
    */
    BOOL CheckPluginConf();

    /*!  @fn
            shutDownPlugin
         @description
            tell all plugins to shutdown themselves
    */
    BOOL execPlugins();

    /*!  @fn
            shutDownPlugin
         @description
            tell all plugins to shutdown themselves
    */
    BOOL shutDownPlugins();

    /*! @fn
            closePlugins
        @description
            Release all resources related to plugins. E.g. the queue for the plugin
    */

    BOOL closePlugins();


    dLinkList* getPluginList();


#ifdef __cplusplus
}
#endif


#endif // PLUGIN_H_INCLUDED
